package cn.com.startai.huadiantrainer.app.activity;

import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.tencent.smtt.export.external.interfaces.IX5WebChromeClient;
import com.tencent.smtt.export.external.interfaces.JsResult;
import com.tencent.smtt.sdk.CookieSyncManager;
import com.tencent.smtt.sdk.DownloadListener;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import java.lang.ref.WeakReference;
import java.util.Queue;

import cn.com.startai.huadiantrainer.R;
import cn.com.startai.huadiantrainer.app.HDTrainerApp;
import cn.com.startai.huadiantrainer.app.view.DialogUtils;
import cn.com.startai.huadiantrainer.app.view.X5WebView;
import cn.com.startai.huadiantrainer.global.Debuger;
import cn.com.startai.huadiantrainer.js.ICallJS;
import cn.com.startai.huadiantrainer.mutual.IJsInterfaceInstance;
import cn.com.startai.huadiantrainer.mutual.JsActivity;
import cn.com.startai.qxcommon.busi.huadian.HDDataCreater;
import cn.com.startai.qxcommon.busi.huadian.bean.HDBackPressReport;
import cn.com.startai.qxcommon.protocol.QXMessage;
import cn.com.swain.baselib.Queue.SyncLimitQueue;
import cn.com.swain.baselib.app.utils.StatusBarUtil;
import cn.com.swain.baselib.jsInterface.AbsJsInterface;
import cn.com.swain.baselib.jsInterface.IotContent.response.ResponseMethodUtil;
import cn.com.swain.baselib.log.Tlog;

/**
 * author Guoqiang_Sun
 * date 2019/5/10
 * desc
 */
public abstract class WebActivity extends AppCompatActivity implements ICallJS {

    protected String TAG = HDTrainerApp.TAG;
    private static final String URL_H5_INDEX = "file:///android_asset/webpage/index.html";
    private X5WebView mWebView;

    private UiHandler mUiHandler;
    private String backPressMethod;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Tlog.d(TAG, "WebActivity onCreate()");

        StatusBarUtil.fullscreenShowBarFontWhite(getWindow());
        getWindow().setFormat(PixelFormat.TRANSLUCENT);

        getWindow()
                .setFlags(
                        android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                        android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

        if (mWebView == null) {
            setContentView(R.layout.activity_main);
            mWebView = findViewById(R.id.x5WebView);
        }

        if (mUiHandler == null) {
            mUiHandler = new UiHandler(this);
        }

    }

    private long loadUrlTs;

    protected void loadWEB() {

        if (this.mWebView == null) {
            Tlog.e(TAG, "WebActivity loadWEB mWebView is null ");
            return;
        }

        AbsJsInterface absJsInterface = getJsInterface();

        if (absJsInterface != null) {
            Tlog.i(TAG, "WebActivity addJavascriptInterface :" + absJsInterface.getName());
            this.mWebView.addJavascriptInterface(absJsInterface.getJsInterface(), absJsInterface.getName());
        } else {
            Tlog.e(TAG, "WebActivity loadWEB absJsInterface is null ");
        }

        this.mWebView.setWebViewClient(new MWebViewClient());

        this.mWebView.setWebChromeClient(new MWebChromeClient());

        this.mWebView.setDownloadListener(new MDownloadListener());

        loadUrlTs = System.currentTimeMillis();
        String loadUrl = getLoadUrl();
        Tlog.i(TAG, "WebActivity start loadUrl " + loadUrl);
        this.mWebView.loadUrl(loadUrl);
        Tlog.i(TAG, "WebActivity loadUrl take up time:" + (System.currentTimeMillis() - loadUrlTs));

        mCanCallJs = true;

        CookieSyncManager.createInstance(this);
        CookieSyncManager.getInstance().sync();

        if (mMethodCache.size() > 0) {
            String method;
            while ((method = mMethodCache.poll()) != null) {
                Tlog.e("poll cache method: " + method);
                if (mUiHandler != null) {
                    mUiHandler.obtainMessage(MSG_WHAT_LOAD_JS, method).sendToTarget();
                } else {
                    Tlog.e("LoadJs mUiHandler is null; " + method);
                }
            }
        }

    }

    private IJsInterfaceInstance mJsInterface;

    /**
     * 注册获取Js接口实例的接口类
     */
    protected void regIJsInterfaceInstance(IJsInterfaceInstance mJsInterface) {
        this.mJsInterface = mJsInterface;
    }

    protected AbsJsInterface getJsInterface() {
        return mJsInterface != null ? mJsInterface.getJsInterface() : null;
    }

    private final Queue<String> mMethodCache = new SyncLimitQueue<>(Byte.MAX_VALUE);

    // webView interface load finish
    private volatile boolean mCanCallJs = false;

    @Override
    public void callJs(String method) {

        if (mCanCallJs) {
            if (mUiHandler != null) {
                mUiHandler.obtainMessage(MSG_WHAT_LOAD_JS, method).sendToTarget();
            }
        } else {
            Tlog.e("LoadJs() web not showed; add to cache: " + method);
            mMethodCache.offer(method);
        }

    }

    private static final int MSG_WHAT_LOAD_JS = 0x01;

    private void handleMessage(Message msg) {
        if (msg.what == MSG_WHAT_LOAD_JS) {
            if (mWebView != null) {
                String method = (String) msg.obj;
                if (Debuger.isLogDebug) {
                    Tlog.d(JsActivity.TAG, "loadUrl:" + method);
                }
                mWebView.loadUrl(method);
            }
        }
    }

    /**
     * H5 加载的资源路径
     */
    protected String getLoadUrl() {
        return URL_H5_INDEX;
    }

    @Override
    public void onBackPressed() {
        if (backPressMethod == null) {
            QXMessage appReportQXMsg = HDDataCreater.getAppReportQXMsg(0, new HDBackPressReport());
            backPressMethod = ResponseMethodUtil.toJsMethod(appReportQXMsg.toJson());
        }
        callJs(backPressMethod);
    }

    @Override
    protected void onResume() {
        Tlog.d(TAG, "WebActivity onResume()");
        super.onResume();
    }

    @Override
    protected void onPause() {
        Tlog.d(TAG, "WebActivity onPause()");
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        Tlog.d(TAG, "WebActivity onDestroy()");
        mJsInterface = null;
        mCanCallJs = false;
        if (mUiHandler != null) {
            mUiHandler.removeCallbacksAndMessages(null);
            mUiHandler.releaseWr();
            mUiHandler = null;
        } else {
            Tlog.e(TAG, " WebActivity onDestroy mUiHandler==null");
        }

        if (mWebView != null) {
            mWebView.stopLoading();
            mWebView.destroy();
            mWebView = null;
        } else {
            Tlog.e(TAG, " WebActivity onDestroy mWebView==null");
        }

        super.onDestroy();
    }

    private class MDownloadListener implements DownloadListener {

        @Override
        public void onDownloadStart(String arg0, String arg1, String arg2,
                                    String arg3, long arg4) {
        }
    }

    private class MWebChromeClient extends WebChromeClient {

        @Override
        public boolean onJsConfirm(WebView arg0, String arg1, String arg2,
                                   JsResult arg3) {
            return super.onJsConfirm(arg0, arg1, arg2, arg3);
        }

        /**
         * 全屏播放配置
         */
        @Override
        public void onShowCustomView(View view,
                                     IX5WebChromeClient.CustomViewCallback customViewCallback) {
            super.onShowCustomView(view, customViewCallback);
        }

        @Override
        public void onHideCustomView() {
            super.onHideCustomView();
        }


        @Override
        public boolean onJsAlert(WebView arg0, String arg1, String arg2,
                                 JsResult arg3) {
            //这里写入自定义的window alert
            DialogUtils.alert(WebActivity.this, arg2, arg3);
            return super.onJsAlert(arg0, arg1, arg2, arg3);
        }

    }

    private class MWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }

        private boolean firstLoad = true;
        private long pageStarted;

        @Override
        public void onPageStarted(WebView webView, String s, Bitmap bitmap) {
            if (Debuger.isLogDebug && firstLoad) {
                pageStarted = System.currentTimeMillis();
                Tlog.d(TAG, "WebActivity first page load started take up time:"
                        + (pageStarted - loadUrlTs));
            }
            super.onPageStarted(webView, s, bitmap);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if (Debuger.isLogDebug && firstLoad) {
                Tlog.d(TAG, "WebActivity first page load finish take up time:"
                        + (System.currentTimeMillis() - pageStarted));
                Tlog.d(TAG, "WebActivity first load url finish take up time:"
                        + (System.currentTimeMillis() - loadUrlTs));
            }
            firstLoad = false;
            super.onPageFinished(view, url);
        }
    }


    private static class UiHandler extends Handler {

        private WeakReference<WebActivity> wr;

        void releaseWr() {
            if (wr != null) {
                wr.clear();
            }
            wr = null;
        }

        UiHandler(WebActivity act) {
            super(Looper.getMainLooper());

            wr = new WeakReference<>(act);

        }


        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            WebActivity act;

            if (wr != null && (act = wr.get()) != null) {
                act.handleMessage(msg);
            } else {
                Tlog.e("<UiHandler> WebHomeActivity == null ");
            }

        }
    }

}
